using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using ExitGames.Client.Photon;
using UnityEngine;

public class GGNetworkPhoton : GGNetwork
{
	public class Message
	{
		public byte[] bytes;

		public float lag;

		public float timePassed;
	}

	protected MemoryStream readBuffer;

	protected MemoryStream writeBuffer;

	protected BinaryReader reader;

	protected BinaryWriter writer;

	protected OnOverflow onOverflow;

	protected long beginPosition;

	protected int curMessageLength;

	protected long curMessageReadPos;

	public float lag;

	protected List<Message> unsendMessages = new List<Message>();

	protected bool doSendStarted;

	protected override void Init()
	{
		base.Init();
		readBuffer = new MemoryStream(new byte[1024]);
		writeBuffer = new MemoryStream(new byte[1024]);
		reader = new BinaryReader(readBuffer);
		writer = new BinaryWriter(writeBuffer);
		ClearBuffers();
		if (PhotonNetwork.PhotonServerSettings == null)
		{
			ServerSettings serverSettings = new ServerSettings();
			serverSettings.AppID = "2acd5781-b2dc-49de-9e2b-b57ed2f3ea2d";
			PhotonNetwork.PhotonServerSettings = serverSettings;
		}
		PhotonNetwork.OnEventCall = (PhotonNetwork.EventCallback)Delegate.Combine(PhotonNetwork.OnEventCall, new PhotonNetwork.EventCallback(onEvent));
	}

	private void onEvent(byte eventCode, object message, int senderId)
	{
		byte[] array = message as byte[];
		if (array != null)
		{
			onMessage(array);
		}
	}

	private void onMessage(byte[] b)
	{
		if (readBuffer.Capacity - readBuffer.Length < b.Length + 1)
		{
			if (onOverflow != 0)
			{
				return;
			}
			readBuffer.SetLength(0L);
		}
		long position = readBuffer.Position;
		readBuffer.Write(b, 0, b.Length);
		readBuffer.Seek(position, SeekOrigin.Begin);
		CallOnMessageReceived();
	}

	public override int ConnectedPlayers()
	{
		return PhotonNetwork.otherPlayers.Length;
	}

	public override bool isInError()
	{
		return false;
	}

	public override void StartServer(string name)
	{
		PhotonNetwork.ConnectUsingSettings(name);
	}

	public override void StartToServer(string name, ServerType type)
	{
		if (type == ServerType.MainServer)
		{
			PhotonNetwork.ConnectUsingSettings(name);
		}
		else
		{
			PhotonNetwork.ConnectToBestCloudServer(name);
		}
	}

	public override void StopServer()
	{
		PhotonNetwork.Disconnect();
	}

	public override void StartClient(string name)
	{
	}

	public override bool Start(string name)
	{
		return PhotonNetwork.ConnectUsingSettings(name);
	}

	public override bool isReady()
	{
		return PhotonNetwork.connectedAndReady;
	}

	public override void LeaveRoom()
	{
		PhotonNetwork.LeaveRoom();
	}

	public override bool CreateRoom(string name, string levelName, int maxPlayers, bool isVisible)
	{
		if (string.IsNullOrEmpty(levelName))
		{
			return PhotonNetwork.CreateRoom(name, isVisible, true, maxPlayers);
		}
		ExitGames.Client.Photon.Hashtable hashtable = new ExitGames.Client.Photon.Hashtable();
		hashtable.Add("levelName", levelName);
		GGDebug.DebugLog("Creating room " + levelName);
		return PhotonNetwork.CreateRoom(name, isVisible, true, maxPlayers, hashtable, null);
	}

	public override bool JoinRoom(string roomName)
	{
		return PhotonNetwork.JoinRoom(roomName);
	}

	public override bool JoinOrCreateRoom(string roomName)
	{
		RoomOptions roomOptions = new RoomOptions();
		roomOptions.isVisible = false;
		roomOptions.maxPlayers = 2;
		RoomOptions roomOptions2 = roomOptions;
		return PhotonNetwork.JoinOrCreateRoom(roomName, roomOptions2, TypedLobby.Default);
	}

	public override bool JoinRandomRoomWithFilter(string roomName, string sqlFilter)
	{
		TypedLobby typedLobby = new TypedLobby(roomName, LobbyType.SqlLobby);
		RoomOptions roomOptions = new RoomOptions();
		roomOptions.isVisible = true;
		roomOptions.maxPlayers = 2;
		RoomOptions roomOptions2 = roomOptions;
		ExitGames.Client.Photon.Hashtable hashtable = new ExitGames.Client.Photon.Hashtable();
		hashtable.Add("levelName", roomName);
		return PhotonNetwork.JoinRandomRoom(hashtable, 2, MatchmakingMode.FillRoom, typedLobby, sqlFilter);
	}

	public override bool CreateRoomForFilter(string roomName, object[] properties)
	{
		RoomOptions roomOptions = new RoomOptions();
		roomOptions.isOpen = true;
		roomOptions.isVisible = true;
		roomOptions.maxPlayers = 2;
		roomOptions.customRoomProperties = new ExitGames.Client.Photon.Hashtable();
		roomOptions.customRoomProperties.Add("levelName", roomName);
		List<string> list = new List<string>();
		int num = 0;
		foreach (object value in properties)
		{
			string text = "C" + num;
			roomOptions.customRoomProperties.Add(text, value);
			list.Add(text);
			num++;
		}
		roomOptions.customRoomPropertiesForLobby = list.ToArray();
		TypedLobby typedLobby = new TypedLobby(roomName, LobbyType.SqlLobby);
		return PhotonNetwork.CreateRoom(null, roomOptions, typedLobby);
	}

	public override bool JoinRandomRoom(string levelName)
	{
		if (string.IsNullOrEmpty(levelName))
		{
			return PhotonNetwork.JoinRandomRoom();
		}
		ExitGames.Client.Photon.Hashtable hashtable = new ExitGames.Client.Photon.Hashtable();
		hashtable.Add("levelName", levelName);
		GGDebug.DebugLog("Joining room " + levelName);
		return PhotonNetwork.JoinRandomRoom(hashtable, 0);
	}

	public override bool isClientServerCapable()
	{
		return true;
	}

	public override void BeginWrite(int messageType)
	{
		writeBuffer.SetLength(0L);
		beginPosition = writeBuffer.Position;
		AddInt(0);
		AddInt(base.protocolVersion);
		AddInt(messageType);
	}

	public override void AddInt(int i)
	{
		writer.Write(i);
	}

	public override void AddFloat(float f)
	{
		writer.Write(f);
	}

	public override void AddString(string s)
	{
		writer.Write(s);
	}

	public override void AddBool(bool b)
	{
		writer.Write(b);
	}

	public override void AddVector3(Vector3 v)
	{
		AddFloat(v.x);
		AddFloat(v.y);
		AddFloat(v.z);
	}

	public override void AddFloatRange(FloatRange q)
	{
		AddFloat(q.min);
		AddFloat(q.max);
	}

	public override void EndWrite()
	{
		long position = writeBuffer.Position;
		writeBuffer.Position = beginPosition;
		writer.Write((int)(position - beginPosition));
		writeBuffer.Position = position;
		writer.Flush();
	}

	public override void BeginRead()
	{
		curMessageReadPos = readBuffer.Position;
		curMessageLength = GetInt();
		base.curMessageProtocolVersion = GetInt();
		curMessageType = GetInt();
	}

	public override int GetInt()
	{
		return reader.ReadInt32();
	}

	public override float GetFloat()
	{
		return reader.ReadSingle();
	}

	public override string GetString()
	{
		return reader.ReadString();
	}

	public override bool GetBool()
	{
		return reader.ReadBoolean();
	}

	public override Vector3 GetVector3()
	{
		return new Vector3(GetFloat(), GetFloat(), GetFloat());
	}

	public override FloatRange GetFloatRange()
	{
		FloatRange result = default(FloatRange);
		result.min = GetFloat();
		result.max = GetFloat();
		return result;
	}

	public override void EndRead()
	{
		long num = readBuffer.Position - curMessageReadPos;
		if (num < curMessageLength)
		{
			reader.ReadBytes((int)(curMessageLength - num));
		}
	}

	public override void ClearBuffers()
	{
		readBuffer.Seek(0L, SeekOrigin.Begin);
		readBuffer.SetLength(0L);
		writeBuffer.Seek(0L, SeekOrigin.Begin);
		writeBuffer.SetLength(0L);
	}

	public override void SetOnOverflow(OnOverflow o)
	{
		onOverflow = o;
	}

	public override bool HasData()
	{
		return readBuffer.Position < readBuffer.Length;
	}

	public override void Send(bool reliable, byte channel)
	{
		writer.Flush();
		if (lag <= 0f)
		{
			RaiseEventOptions raiseEventOptions = new RaiseEventOptions();
			raiseEventOptions.SequenceChannel = channel;
			PhotonNetwork.RaiseEvent(1, writeBuffer.ToArray(), reliable, raiseEventOptions);
		}
		else
		{
			unsendMessages.Add(new Message
			{
				bytes = writeBuffer.ToArray(),
				lag = UnityEngine.Random.Range(0.5f, 1.5f)
			});
			BehaviourSingleton<GGSingleBehaviour>.instance.StartCoroutine(DoSend());
		}
	}

	public IEnumerator DoSend()
	{
		if (doSendStarted)
		{
			yield break;
		}
		doSendStarted = true;
		while (unsendMessages.Count != 0)
		{
			Message firstMessage = unsendMessages[0];
			firstMessage.timePassed += Time.deltaTime;
			if (firstMessage.timePassed > firstMessage.lag)
			{
				PhotonNetwork.RaiseEvent(1, firstMessage.bytes, true, null);
				unsendMessages.RemoveAt(0);
			}
			yield return null;
		}
		doSendStarted = false;
	}
}
